package com.example.vpn_demo.packet

import android.util.Log
import java.nio.ByteBuffer
import java.nio.ByteOrder

object PacketParser {
    private const val TAG = "PacketParser"
    
    // IP协议号
    private const val PROTOCOL_TCP = 6
    private const val PROTOCOL_UDP = 17
    
    // 常用端口
    private const val HTTP_PORT = 80
    private const val HTTPS_PORT = 443
    
    fun parsePacket(buffer: ByteBuffer): NetworkPacket? {
        try {
            buffer.order(ByteOrder.BIG_ENDIAN)
            
            // 解析IP头部
            val ipVersion = buffer.get(0).toInt() shr 4 and 0xF
            if (ipVersion != 4) return null // 只处理IPv4
            
            val ipHeaderLength = (buffer.get(0).toInt() and 0xF) * 4
            val totalLength = buffer.getShort(2).toInt() and 0xFFFF
            val protocol = buffer.get(9).toInt() and 0xFF
            val sourceIp = formatIpAddress(buffer.getInt(12))
            val destIp = formatIpAddress(buffer.getInt(16))
            
            // 只处理TCP协议
            if (protocol != PROTOCOL_TCP) return null
            
            // 解析TCP头部
            buffer.position(ipHeaderLength)
            val sourcePort = buffer.getShort().toInt() and 0xFFFF
            val destPort = buffer.getShort().toInt() and 0xFFFF
            
            // 只处理HTTP相关端口
            if (destPort != HTTP_PORT && destPort != HTTPS_PORT) return null
            
            buffer.position(buffer.position() + 8) // 跳过序列号和确认号
            val tcpHeaderLength = (buffer.get().toInt() shr 4 and 0xF) * 4
            
            // 计算数据部分
            val totalHeaderLength = ipHeaderLength + tcpHeaderLength
            val dataLength = totalLength - totalHeaderLength
            
            if (dataLength <= 0) return null
            
            // 读取数据部分
            buffer.position(totalHeaderLength)
            val data = ByteArray(dataLength)
            buffer.get(data)
            
            Log.d(TAG, """
                |Packet Info:
                |Source: $sourceIp:$sourcePort
                |Dest: $destIp:$destPort
                |Data Length: $dataLength
            """.trimMargin())
            
            return NetworkPacket(
                sourceIp = sourceIp,
                destIp = destIp,
                sourcePort = sourcePort,
                destPort = destPort,
                data = data
            )
        } catch (e: Exception) {
            Log.e(TAG, "Error parsing packet", e)
            return null
        }
    }
    
    private fun formatIpAddress(ip: Int): String {
        return String.format(
            "%d.%d.%d.%d",
            ip shr 24 and 0xFF,
            ip shr 16 and 0xFF,
            ip shr 8 and 0xFF,
            ip and 0xFF
        )
    }
}

data class NetworkPacket(
    val sourceIp: String,
    val destIp: String,
    val sourcePort: Int,
    val destPort: Int,
    val data: ByteArray
) {
    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false
        
        other as NetworkPacket
        
        if (sourceIp != other.sourceIp) return false
        if (destIp != other.destIp) return false
        if (sourcePort != other.sourcePort) return false
        if (destPort != other.destPort) return false
        if (!data.contentEquals(other.data)) return false
        
        return true
    }
    
    override fun hashCode(): Int {
        var result = sourceIp.hashCode()
        result = 31 * result + destIp.hashCode()
        result = 31 * result + sourcePort
        result = 31 * result + destPort
        result = 31 * result + data.contentHashCode()
        return result
    }
} 